package reportdb

import (
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/boltdb/bolt"
	"report/constant"
	"report/model"
	"strings"
)

func Login(name string, pwd string) error {

	//	name,pwd,err := parseToken(token)
	//	if err != nil {
	//		return err
	//	}
	loginErr := reportDB.View(func(tx *bolt.Tx) error {
		user := &model.User{}
		if userErr := searchUserByKey(tx, name, user); userErr != nil {
			return userErr
		}
		if user.Password == pwd {
			return nil
		}
		return errors.New("Invalid username or password")
	})

	return loginErr

}

func parseToken(token string) (string, string, error) {
	str, _ := base64.StdEncoding.DecodeString(token)
	arr := strings.Split(string(str), ":")
	if len(arr) < 2 {
		return "", "", errors.New("Invalid request.")
	}
	name := arr[0]
	pwd := arr[1]
	return name, pwd, nil
}

func AddUser(user model.User) error {

	err := reportDB.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte(constant.USER_TABLE))
		if err != nil {
			return fmt.Errorf("create bucket: %s", err)
		}
		byt, _ := json.Marshal(user)
		return b.Put([]byte(user.Name), byt)
	})
	return err
}

func IsAdmin(token string) (bool, error) {
	name, pwd, err := parseToken(token)
	if err != nil {
		return false, err
	}
	user := &model.User{}
	userErr := reportDB.View(func(tx *bolt.Tx) error {
		return searchUserByKey(tx, name, user)
	})

	if userErr != nil {
		return false, userErr
	}
	if user.Password == pwd && user.Role == "admin" {
		return true, nil
	} else {
		return false, errors.New("Invalid login or the role is not admin.")
	}
}

func searchUserByKey(tx *bolt.Tx, key string, user *model.User) error {
	if b := tx.Bucket([]byte(constant.USER_TABLE)); b != nil {
		if v := b.Get([]byte(key)); v != nil {
			fmt.Println("user content:", string(v))
			return json.Unmarshal(v, user)
		}
		return fmt.Errorf("Can't find the record by key:%s \n", key)
	}
	return fmt.Errorf("Table %s does not exist.", constant.USER_TABLE)
}

func InitAdminUser() error {
	adminUser := model.User{Name: "admin", Password: "admin", Role: "admin"}
	name := "admin"
	if viewErr := reportDB.View(func(tx *bolt.Tx) error {
		return searchUserByKey(tx, name, &adminUser)
	}); viewErr == nil {
		return nil
	}

	fmt.Println("Cannot find the admin user while initial, will create a new one.")
	return AddUser(adminUser)
}
